package com.cci.kangdao.service.impl;

import com.cci.kangdao.aop.UserThreadLocal;
import com.cci.kangdao.crmapi.CRMApiUtils;
import com.cci.kangdao.crmapi.CRMResponeEntity;
import com.cci.kangdao.dao.*;
import com.cci.kangdao.dao.model.CompanyT;
import com.cci.kangdao.dao.model.SSRepairT;
import com.cci.kangdao.dao.model.UserT;
import com.cci.kangdao.dao.model.WorkOrderT;
import com.cci.kangdao.redis.RedisClientUtils;
import com.cci.kangdao.service.NoticeService;
import com.cci.kangdao.service.PropertiesUtils;
import com.cci.kangdao.service.ServiceTechniciansListService;
import com.cci.kangdao.utilTool.*;
import com.cci.kangdao.wechatOrder.dao.WeChatUserRelationTDao;
import com.cci.kangdao.wechatOrder.service.IOrderPushMessageService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//服务技师
@Service("ServiceTechniciansListService")
public class ServiceTechniciansListServiceImpl implements ServiceTechniciansListService {

	private Logger log = Logger.getLogger(this.getClass().getName());

	@Autowired
	private UserTDao userTDao;

	@Autowired
	private WorkOrderPrincipalTDao workOrderPrincipalTDao;

	@Autowired
	private EngineerQualifyTDao engineerQualifyTDao;

	@Autowired
	private EngineTypeTDao engineTypeTDao;

	@Autowired
	private LoginDao loginDao;

	@Resource
	private WorkOrderRepairDao workOrderRepairDao;

	@Resource
	private CRMPlatformServiceDao platformServiceDao;

	@Autowired
	private WorkOrderTDao workOrderTDao;

	@Autowired
	private RelationShipTDao relationShipTDao;

	@Autowired
	private CompanyTDao companyTDao;

	@Autowired
	private RedisClientUtils redisClientUtils;

	@Resource
	private SMNTDao smntDao;

	@Resource
	private EngineMsgDao engineMsgDao;
	@Resource
	private NoticeService noticeService;
	@Resource
	private ServiceStationDao serviceStationDao;
	@Resource
	private PropertiesUtils propertiesUtils;
	@Resource
	private IOrderPushMessageService iOrderPushMessageService;
	@Resource
	private WeChatUserRelationTDao weChatUserRelationTDao;
	@Resource
	private SSRepairTDao sSRepairTDao;

	// 根据服务站id和服务技师用户id获取服务技师资质列表
	@Transactional
	@Override
	public ModelAndView getEngineerQualifyListByServiceStationIdUserId(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); // 封装给前端的所有数据，消息和状态
			String ServiceStationID = (String) map.get("ServiceStationID");
			if (StringUtils.isEmpty(ServiceStationID)) { // 判断服务站id是否为空
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务站id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long serviceChannel = MapUtils.getLongValue(map, "ServiceChannel", 3); // 服务渠道主键id
			Long  orderId = MapUtils.getLong(map, "orderId",null); // 服务渠道主键id
			JSONArray jsonArray = new JSONArray(); // 封装所有数据
			boolean isTechSupport = false;
			if(null != orderId && orderId != 0){
				WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId);
				if(null != workOrderT && null != workOrderT.getIsTechSupport() && workOrderT.getIsTechSupport() == 1){
					map.put("companyId",workOrderT.getOrderChannel());
					isTechSupport = true;
				}
			}
			List<UserT> serviceTechniciansList = new ArrayList<>();
			if(isTechSupport){
				//技术支持的技师列表
				serviceTechniciansList = userTDao.getGreatCraftsmanListByServiceStationId(map);
			} else {
				// 根据服务站id获取所有服务技师
				serviceTechniciansList = userTDao.getServiceTechniciansListByServiceStationId(map);
			}

			if (CollectionUtils.isNotEmpty(serviceTechniciansList)) { // 如果指定服务站下有服务技师
				for (UserT userT : serviceTechniciansList) { // 遍历技师集合
					map.put("UserId", userT.getId()); // 往map中存值，方便dao中绑定查询
					JSONObject jsonObject = new JSONObject();
					jsonObject.put("userId", userT.getId()); // 技师id
					jsonObject.put("userName", userT.getContact()); // 技师姓名
					// 获取服务技师资质
					String engineerQualifyName = "";
					if (serviceChannel == 1) { // DBU获取服务技师资质逻辑
						String promotionId = userT.getPromotionId(); // CRM同步技师资质时会填充这个字段的值
						// 根据promotionId获取技师资质信息
						Map<String, Object> engineerQualifyTMap = engineerQualifyTDao
								.getEngineerQualifyTByPromotionId(promotionId);
						if (MapUtils.isNotEmpty(engineerQualifyTMap)) {
                            String serviceModelNameIds = engineerQualifyTMap.get("ServiceModelNameIds").toString(); // SMN表主键id
                            List<String> SMNList = StringToool.getStringList(serviceModelNameIds, ",");                                                                                    // 已逗号分隔
							// 获取所有SMN信息 smnList就是资质
                            List<Map<String, Object>> smnList = smntDao.getSMNListByIds(SMNList);
                            int index = 1;
							if (CollectionUtils.isNotEmpty(smnList)) {
								for (Map<String, Object> smn : smnList) {
									if (index < smnList.size()) {
										engineerQualifyName += smn.get("SMNname") + "/";
									} else {
										engineerQualifyName += smn.get("SMNname");
									}
									index++;
								}
							}
						}
					} else { // 除了DBU获取服务技师资质逻辑不一样 别的服务渠道都用以下逻辑
						List<String> engineerQualifyNames = engineerQualifyTDao
								.getEngineerQualifyListByPhone(userT.getPhone());
						int index = 1;
						if (CollectionUtils.isNotEmpty(engineerQualifyNames)) {
							for (String s : engineerQualifyNames) {
								if (index < engineerQualifyNames.size()) {
									engineerQualifyName += s + "/";
								} else {
									engineerQualifyName += s;
								}
								index++;
							}
						}
					}
					// 把资质数据放入jsonObject内
					if (StringUtils.isEmpty(engineerQualifyName)) {
						jsonObject.put("engineTypeArr", new JSONArray());
					} else {
						JSONArray enginTypeNames = new JSONArray();
						JSONObject enginTypeName = new JSONObject();
						enginTypeName.put("engineTypeName", engineerQualifyName);
						enginTypeNames.put(enginTypeName);
						jsonObject.put("engineTypeArr", enginTypeNames);
					}

					// 获取服务技师是否空闲，若workOrderPrincipalTList不为空说明服务技师在忙，反之空闲
					int workOrderPrincipalTCount = workOrderPrincipalTDao.getWorkOrderPrincipalCountByUserId(map);
					if (workOrderPrincipalTCount != 0) {
						// 如果技师在忙，返给前端isBusy的值为1(1代表繁忙)
						jsonObject.put("isBusy", 1);
					} else {
						// 如果技师空闲，返给前端isBusy的值为0(0代表空闲)
						jsonObject.put("isBusy", 0);
					}
					jsonArray.put(jsonObject);
				}
			} else {
				obj.put("data", new JSONObject().put("EngineerQualifyList", new JSONArray())); // 把封装的数据返给手机端
				obj.put("status", 0);
				obj.put("msg", "该服务站未查到服务技师");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			obj.put("data", new JSONObject().put("EngineerQualifyList", jsonArray)); // 把封装的数据返给手机端
			obj.put("status", 0);
			obj.put("msg", "查询成功");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			// 主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 根据服务站id获取仅DCEC渠道授权服务站是否有资质（超权限创建工单）
	 * 
	 * @param map
	 * @return
	 */
	@Override
	public ModelAndView getEngineerQualifyVerifyByServiceStationId(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); // 封装给前端的所有数据，消息和状态
			String ServiceStationID = (String) map.get("ServiceStationID");
			if (StringUtils.isEmpty(ServiceStationID)) { // 判断服务站id是否为空
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务站id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			long serviceChannel = MapUtils.getLongValue(map, "ServiceChannel", 3); // 服务渠道主键id
			// dcec渠道需求
			if (serviceChannel == 3) {
				obj.put("status", 0);
				obj.put("msg", "查询成功");
				String orderType = MapUtils.getString(map, "OrderType");
				CRMResponeEntity cRMResponeEntity = CRMApiUtils.getCRMServiceApi().validationCert(Long.valueOf(ServiceStationID), orderType);
				if (cRMResponeEntity.getStatus() != 0) {
					log.error("查询资质失败:" + cRMResponeEntity.getStatus() + ",错误信息:"
							+ cRMResponeEntity.getMessage());
					obj.put("status", 1);
					obj.put("msg", cRMResponeEntity.getMessage());
					ParameterTool.writeResponse(response, obj.toString());
					return null;
				}
				obj.put("data", new JSONObject().put("hasQualify", cRMResponeEntity.getData().getInt("isExist")==1?1:0));
				ParameterTool.writeResponse(response, obj.toString());
				return null;
//				JSONObject jsonObj = queryDcecChannelSmn(ServiceStationID);
//				ParameterTool.writeResponse(response, jsonObj.toString());
//				return null;
			}
			// 根据服务站id获取所有服务技师
			List<UserT> serviceTechniciansList = userTDao.getServiceTechniciansListByServiceStationId(map);
			StringBuilder engineerQualifyName = new StringBuilder();
			if (CollectionUtils.isNotEmpty(serviceTechniciansList)) { // 如果指定服务站下有服务技师
				for (UserT userT : serviceTechniciansList) { // 遍历技师集合
					// 获取服务技师资质
					if (serviceChannel == 1) { // DBU获取服务技师资质逻辑
						String promotionId = userT.getPromotionId(); // CRM同步技师资质时会填充这个字段的值
						// 根据promotionId获取技师资质信息
						Map<String, Object> engineerQualifyTMap = engineerQualifyTDao
								.getEngineerQualifyTByPromotionId(promotionId);
						if (MapUtils.isNotEmpty(engineerQualifyTMap)) {
							String serviceModelNameIds = engineerQualifyTMap.get("ServiceModelNameIds").toString(); // SMN表主键id
																													// 已逗号分隔
                            List<String> SMNList = StringToool.getStringList(serviceModelNameIds, ",");
							// 获取所有SMN信息 smnList就是资质
                            List<Map<String, Object>> smnList = smntDao.getSMNListByIds(SMNList);
                            int index = 1;
							if (CollectionUtils.isNotEmpty(smnList)) {
								for (Map<String, Object> smn : smnList) {
									if (index < smnList.size()) {
										engineerQualifyName.append(smn.get("SMNname") + "/");
									} else {
										engineerQualifyName.append(smn.get("SMNname"));
									}
									index++;
								}
							}
						}
					} else { // 除了DBU获取服务技师资质逻辑不一样 别的服务渠道都用以下逻辑
						// 查询服务站下的人员是否有资质(smn就是资质)
						List<String> engineerQualifyNames = engineerQualifyTDao
								.getEngineerQualifySMNListByPhone(userT.getPhone());
						obj.put("status", 0);
						obj.put("msg", "查询成功");
						obj.put("data", new JSONObject().put("hasQualify", 1));// 有资质
						ParameterTool.writeResponse(response, obj.toString());
						return null;
						// 资质需要sf同步过来，但它的手机号不一定在我们系统中有，所以为了顺利通过培训，先把根据手机号查询资质的逻辑去掉，等培训完在商量更好的解决方案
//						if(engineerQualifyNames != null && !engineerQualifyNames.isEmpty()){
//							obj.put("data", new JSONObject().put("hasQualify", 1));//有资质
//							ParameterTool.writeResponse(response, obj.toString());
//							return null;
//						}
					}
				}
				obj.put("status", 0);
				obj.put("msg", "查询成功");
				if (engineerQualifyName.length() > 0) {
					obj.put("data", new JSONObject().put("hasQualify", 1));// 有资质
				} else {
					obj.put("data", new JSONObject().put("hasQualify", 0));// 没资质
				}
			} else {
				obj.put("data", new JSONObject().put("EngineerQualifyList", new JSONArray())); // 把封装的数据返给手机端
				obj.put("status", 0);
				obj.put("msg", "该服务站未查到服务技师");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * @description: dcec渠道新建工单时验证服务站是否有资质
	 * @param:
	 * @return:
	 * @exception:
	 * @author: shiliqiang
	 * @company: CTY Technology Co.,Ltd
	 * @since: 2021/12/8 13:27
	 * @version: V1.0
	 */
	private JSONObject queryDcecChannelSmn(String serviceStationId) throws JSONException {
		JSONObject obj = new JSONObject(); // 封装给前端的所有数据，消息和状态
		Map<String, Object> map = new HashMap<>();
		map.put("serviceStationId", serviceStationId);
		map.put("companyID", 3);
		List<SSRepairT> ssRepairList = serviceStationDao.getSSRepairListByServiceStaionIdForDCEC(map);
		if (ssRepairList != null && ssRepairList.size() > 0) {
			// 跟SF沟通确认，我们只要查询SF同步过来的服务站下是否有数据即可
			List<String> engineerQualifyNames = engineerQualifyTDao
					.getEngineerQualifySMNListByStationNo(ssRepairList.get(0).getBusinessno());
			// 资质需要sf同步过来，但它的手机号不一定在我们系统中有，所以为了顺利通过培训，先把根据手机号查询资质的逻辑去掉，等培训完在商量更好的解决方案
			if (engineerQualifyNames != null && !engineerQualifyNames.isEmpty()) {
				obj.put("status", 0);
				obj.put("msg", "服务站有资质");
				obj.put("data", new JSONObject().put("hasQualify", 1));// 有资质
				return obj;
			} else {
				// 正常业务服务站和授权是一对一关系，这里防止出现一对多（最多是一对二）
				if (ssRepairList.size() > 1) {
					engineerQualifyNames = engineerQualifyTDao
							.getEngineerQualifySMNListByStationNo(ssRepairList.get(1).getBusinessno());
					if (engineerQualifyNames != null && !engineerQualifyNames.isEmpty()) {
						obj.put("status", 0);
						obj.put("msg", "服务站有资质");
						obj.put("data", new JSONObject().put("hasQualify", 1));// 有资质
						return obj;
					}
				}
				obj.put("status", 0);
				obj.put("msg", "SF未同步此服务站的资质");
				return obj;
			}
		}
		obj.put("data", new JSONObject().put("EngineerQualifyList", new JSONArray())); // 把封装的数据返给手机端
		obj.put("status", 0);
		obj.put("msg", "SF未给此服务站授权");
		return obj;
	}

	// 判断服务技师是否有资质
	@Transactional
	@Override
	public ModelAndView isHaveEngineerQualify(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); // 封装给前端的所有数据，消息和状态
			// 调用公共方法获取是否有资质 0 ：否 1：是
			int isHaveEngineerQualify = getHaveEngineerQualify(map);
			obj.put("data", new JSONObject().put("isHaveEngineerQualify", isHaveEngineerQualify));
			obj.put("status", 0);
			obj.put("msg", "success");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			// 主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

	// 判断服务技师是否有资质的公共方法
	int getHaveEngineerQualify(Map<String, Object> map) {
		long serviceChannel = MapUtils.getLongValue(map, "ServiceChannel", 1); // 服务渠道主键id
		String engineerUserId = MapUtils.getString(map, "EngineerUserId"); // 服务技师用户主键id
		String esn = MapUtils.getString(map, "ESN");
		UserT userT = loginDao.getUserByid(engineerUserId);// 获取服务技师信息
		String promotionId = userT.getPromotionId(); // CRM同步技师资质时会填充这个字段的值
		// 根据promotionId获取技师资质信息
		int isHaveEngineerQualify = 0; // 标志服务技师是否有资质 默认是否(没有资质)
		if (serviceChannel == 1) { // 代表DBU 目前DBU判断技师是否有维修资质是这个逻辑
			if (StringUtils.isNotEmpty(promotionId)) {
				Map<String, Object> engineerQualifyTMap = engineerQualifyTDao
						.getEngineerQualifyTByPromotionId(promotionId);
				if (MapUtils.isNotEmpty(engineerQualifyTMap)) {
                    String serviceModelNameIds = engineerQualifyTMap.get("ServiceModelNameIds").toString(); // SMN表主键id
                    // 已逗号分隔
                    // 获取所有SMN信息 smnList就是资质
                    List<String> SMNList = StringToool.getStringList(serviceModelNameIds, ",");
                    List<Map<String, Object>> smnList = smntDao.getSMNListByIds(SMNList);
                    Map<String, Object> engineMsg = engineMsgDao.getSMNByESN(esn);
                    if (MapUtils.isNotEmpty(engineMsg)) {
                        String smn = MapUtils.getString(engineMsg, "SMN", "");
                        if (CollectionUtils.isNotEmpty(smnList)) {
                            for (Map<String, Object> smnMap : smnList) {
                                String smn2 = smnMap.get("SMNname").toString();
                                if (smn.equals(smn2)) { // 说明有资质
                                    isHaveEngineerQualify = 1; // 标志有资质
                                    break;
                                }
							}
						}
					}
				}
			}
		}
		return isHaveEngineerQualify;
	}

	// 服务站指派服务技师
	@Transactional
	@Override
	public ModelAndView submitServiceTechnician(Map<String, Object> map) {
		HttpServletResponse response = (HttpServletResponse) map.get("response");
		HttpServletRequest request = (HttpServletRequest) map.get("request");
		try {
			JSONObject obj = new JSONObject(); // 封装给前端的所有数据，消息和状态
			/*
			 * String userADId =
			 * AESTool.decryptString(request.getHeader("userid"));//解密登录人userid UserT userT
			 * = loginDao.getUserByid(userADId);
			 */
			UserT userT = UserThreadLocal.get();
			Long userid = userT.getId();
			String currentTime = LocalTimeUtil.getRealCurrentTime(); // 获取当前时间
			String workOrderId = (String) map.get("workOrderId"); // 工单id
			if ("".equals(workOrderId) || workOrderId == null) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			CompanyT ccecChannelCompany = companyTDao.getCompanyInfoByCompanyNo("CCEC");
			// 新建消息提醒表对象list(可能会推送多人短信提醒)
			List<Map<String, Object>> notifyRecordTMapList = new ArrayList<Map<String, Object>>();
			map.put("ID", Long.parseLong(workOrderId));
			WorkOrderT workOrderT = workOrderTDao.getWorkOrderTById(map);
			if (workOrderT.getOrderStatus() == 7) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "服务商已指派服务技师!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			if (workOrderT.getOrderStatus() == 16) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "工单已被关闭!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			List<UserT> us = loginDao.getUserByPhone(workOrderT.getCustomerPhone());
			String userSmstext = "您有工单已指派技师，工单号" + workOrderT.getOrderNo()+ "，";
			if(workOrderT.getOrderChannel() == 1){
				userSmstext = userSmstext + "属于\"" + workOrderT.getSellType() + "\"" + (StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，";
			}
			userSmstext = userSmstext + "请查看!";

			// 推送短信
			SmsUtils.sendMessage(workOrderT.getCustomerPhone(), userSmstext);
			// 新建消息提醒表对象(保存关于用户消息提醒数据)
			Map<String, Object> yhNotifyRecordTMap = new HashMap<String, Object>();
			yhNotifyRecordTMap.put("OrderId", workOrderId);
			yhNotifyRecordTMap.put("Function", 2); // 派单提醒
			yhNotifyRecordTMap.put("Category", 1); // 新工单提醒
			if (CollectionUtils.isNotEmpty(us)) {
				yhNotifyRecordTMap.put("ReceiverId", us.get(0).getId()); // 接收人
			} else {
				yhNotifyRecordTMap.put("ReceiverId", -1); // 接收人
			}
			yhNotifyRecordTMap.put("Content", userSmstext); // 消息内容
			yhNotifyRecordTMap.put("SendType", 1); // 推送方式1代表短信
			yhNotifyRecordTMap.put("SendTime", currentTime);
			yhNotifyRecordTMap.put("Status", 1);
			yhNotifyRecordTMap.put("ExceptionInfo", "服务站指派服务技师");
			yhNotifyRecordTMap.put("IsRead", 0);
			yhNotifyRecordTMap.put("Flag", 0);
			yhNotifyRecordTMap.put("Creator", userid);
			yhNotifyRecordTMap.put("CreateTime", currentTime);
			notifyRecordTMapList.add(yhNotifyRecordTMap);
			if (CollectionUtils.isNotEmpty(us)) { // 用户在系统中存在，就推送app
				noticeService.push(2, 1, Long.valueOf(workOrderId), us.get(0).getId(), us.get(0).getUserName(), "新工单提醒",
						userSmstext, userSmstext, userid);
			} else {
				noticeService.push(2, 1, Long.valueOf(workOrderId), 0L, "", "新工单提醒", userSmstext, userSmstext, userid);
			}
			// dbu的工单需要推送公众号消息 dbu微信公众号查看工单详情url
			if (workOrderT.getOrderChannel() == 1) {
				String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
				// Map<String, Object> weChatUserRelationTMap =
				// weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(us.get(0).getPhone());
				// if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
				// 拼公众号中查看详情的url
				String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderId);
				// 推送微信公众号消息
				String firstData = "您有一条重要的工单状态信息";
				String keyWord1 = "编号：" + workOrderT.getOrderNo();
				String keyWord2 = "您有工单已指派技师。";
				String keyWord3 = Dictionaries.OrderStatus_07.getName();
				String keyWord4 = UserThreadLocal.get().getContact();
				String remark = "请点击详情查看工单内容";
				iOrderPushMessageService.sendOrderMessage(Long.parseLong(workOrderId), urlFormat, firstData, keyWord1,
						keyWord2, keyWord3, keyWord4, remark);
				// }
			}
			// dcec的工单需要推送公众号消息 dcec微信公众号查看工单详情url
			Integer orderSource;
			try {
				orderSource = workOrderT.getOrderSource();
				if (workOrderT.getOrderChannel() == 3 && orderSource == 6) {
					String dbuWechatWorkOrderInfoUrl = propertiesUtils.getPropertiesValue("DBUWechatWorkOrderInfoUrl");
					// Map<String, Object> weChatUserRelationTMap =
					// weChatUserRelationTDao.getWeChatUserRelationTByUserPhone(us.get(0).getPhone());
					// if (MapUtils.isNotEmpty(weChatUserRelationTMap)) {
					// 拼公众号中查看详情的url
					String urlFormat = String.format(dbuWechatWorkOrderInfoUrl, workOrderId);
					// 推送微信公众号消息
					String firstData = "您有一条重要的工单状态信息";
					String keyWord1 = "编号：" + workOrderT.getOrderNo();
					String keyWord2 = "您有工单已指派技师。";
					String keyWord3 = Dictionaries.OrderStatus_07.getName();
					String keyWord4 = UserThreadLocal.get().getContact();
					String remark = "请点击详情查看工单内容";
					// ########################
					iOrderPushMessageService.sendOrderMessage(Long.parseLong(workOrderId), urlFormat, firstData,
							keyWord1, keyWord2, keyWord3, keyWord4, remark);

				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			// 给主副技师推送短信信息文字
			String smstext = "您有新工单信息，工单号" + workOrderT.getOrderNo() + "，";
			if(workOrderT.getOrderChannel() == 1){
				smstext = smstext + "属于\"" + workOrderT.getSellType() + "\"" + (StringUtils.isNotBlank(workOrderT.getServiceSubtype()) ? "-" + workOrderT.getServiceSubtype() : "") + "，";
			}
			smstext = smstext + "请查看!";
			// ccec给主副技师推送短信信息文字
			String ccecSmstext = "您有新的工单信息待处理，工单号%s，请查看。";
			String msg = workOrderT.getOrderNo();
			if (StringUtils.isNotEmpty(workOrderT.getCCSSOrderNo())) {
				msg += "（FW号" + workOrderT.getCCSSOrderNo() + "）";
			}
			ccecSmstext = String.format(ccecSmstext, msg);
			if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) { // ccec渠道工单 重新赋值提示语
				smstext = ccecSmstext;
			}
			// 获取主技师id(主技师只有一个,必须得有)
			String zhuServiceTechnician = (String) map.get("zhuServiceTechnician");
			if ("".equals(zhuServiceTechnician) || zhuServiceTechnician == null) {
				obj.put("data", "");
				obj.put("status", 1);
				obj.put("msg", "主技师id不能为空!");
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			SmsUtils.sendMessage(loginDao.getUserByUserId(Long.parseLong(zhuServiceTechnician)).getPhone(), smstext);
			// 新建消息提醒表对象(保存关于主技师消息提醒数据)
			Map<String, Object> zhuNotifyRecordTMap = new HashMap<String, Object>();
			zhuNotifyRecordTMap.put("OrderId", workOrderId);
			zhuNotifyRecordTMap.put("Function", 2); // 派单提醒
			zhuNotifyRecordTMap.put("Category", 1); // 新工单提醒
			zhuNotifyRecordTMap.put("ReceiverId", Long.parseLong(zhuServiceTechnician)); // 接收人
			zhuNotifyRecordTMap.put("Content", smstext); // 消息内容
			zhuNotifyRecordTMap.put("SendType", 1); // 推送方式1代表短信
			zhuNotifyRecordTMap.put("SendTime", currentTime);
			zhuNotifyRecordTMap.put("Status", 1);
			zhuNotifyRecordTMap.put("ExceptionInfo", "");
			zhuNotifyRecordTMap.put("IsRead", 0);
			zhuNotifyRecordTMap.put("Flag", 0);
			zhuNotifyRecordTMap.put("Creator", userid);
			zhuNotifyRecordTMap.put("CreateTime", currentTime);
			notifyRecordTMapList.add(zhuNotifyRecordTMap);
			// 推送App提醒消息
			UserT zjs = loginDao.getUserByUserId(Long.parseLong(zhuServiceTechnician));
			if (null != zjs) {
				noticeService.push(2, 1, Long.valueOf(workOrderId), zjs.getId(), zjs.getUserName(), "", smstext,
						smstext, userid);
			}

			// 新建传给CRM技师信息集合
			List<Map<String, Object>> engineerMapList = new ArrayList<>();
			UserT zhuEngineer = loginDao.getUserByid(zhuServiceTechnician);
			Map<String, Object> zhuEngineerMap = new HashMap<>();
			if (null != zhuEngineer) {
				if (StringUtils.isNotEmpty(zhuEngineer.getPromotionId())) { // 技师授权ID
					zhuEngineerMap.put("engineerPromotionId", zhuEngineer.getPromotionId());
				} else {
					zhuEngineerMap.put("engineerPromotionId", "");
				}
				zhuEngineerMap.put("engineerName", zhuEngineer.getContact());
				zhuEngineerMap.put("engineerPhone", zhuEngineer.getPhone());
				zhuEngineerMap.put("isMainengineer", 1); // 是主技师
				map.put("ServiceChannel", workOrderT.getOrderChannel());
				map.put("EngineerUserId", zhuEngineer.getId());
				map.put("ESN", workOrderT.getESN());
				zhuEngineerMap.put("hasCertification", getHaveEngineerQualify(map)); // 是否有资质
			}
			engineerMapList.add(zhuEngineerMap);

			// 新建工单负责人表对象(保存关于主技师工单负责人表数据)
			Map<String, Object> zhuWorkOrderPrincipalTMap = new HashMap<String, Object>(); // 新建消息提醒表对象
			zhuWorkOrderPrincipalTMap.put("OrderId", workOrderId);
			zhuWorkOrderPrincipalTMap.put("OrderStatus", 7); // 待服务技师接单
			zhuWorkOrderPrincipalTMap.put("IsPrincipal", 1); // 是主负责人
			zhuWorkOrderPrincipalTMap.put("PrincipalId", Long.parseLong(zhuServiceTechnician)); // 人员id
			zhuWorkOrderPrincipalTMap.put("Audited", 0);
			zhuWorkOrderPrincipalTMap.put("Flag", 0);
			zhuWorkOrderPrincipalTMap.put("ProcessorId", userid);
			zhuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
			String secondLevelStation = "";
			if (map.containsKey("secondLevelStation")) {
				secondLevelStation = map.get("secondLevelStation").toString();
			}
			zhuWorkOrderPrincipalTMap.put("SecondLevelStation", secondLevelStation);
			workOrderRepairDao.savePrincipal(zhuWorkOrderPrincipalTMap); // 插入并保存主工单负责人表数据
			// 获取副技师id(副技师可以没有，可以一个或多个)
			String fuServiceTechnician = (String) map.get("fuServiceTechnician");
			if (fuServiceTechnician != null && !"".equals(fuServiceTechnician)) {
				String[] fuServiceTechnicians = fuServiceTechnician.split(",");
				for (String s : fuServiceTechnicians) {
					// 把副技师资质信息保存到CRM集合中
					UserT fuEngineer = loginDao.getUserByid(s);
					Map<String, Object> fuEngineerMap = new HashMap<>();
					if (null != fuEngineer) {
						if (StringUtils.isNotEmpty(fuEngineer.getPromotionId())) { // 技师授权ID
							fuEngineerMap.put("engineerPromotionId", fuEngineer.getPromotionId());
						} else {
							fuEngineerMap.put("engineerPromotionId", "");
						}
						fuEngineerMap.put("engineerName", fuEngineer.getContact());
						fuEngineerMap.put("engineerPhone", fuEngineer.getPhone());
						fuEngineerMap.put("isMainengineer", 0); // 是主技师
						map.put("EngineerUserId", fuEngineer.getId());
						fuEngineerMap.put("hasCertification", getHaveEngineerQualify(map)); // 是否有资质
					}
					engineerMapList.add(fuEngineerMap);
					// 新建工单负责人表对象(保存关于副技师工单负责人表数据)
					Map<String, Object> fuWorkOrderPrincipalTMap = new HashMap<String, Object>(); // 新建副技师负责人对象
					fuWorkOrderPrincipalTMap.put("OrderId", workOrderId);
					fuWorkOrderPrincipalTMap.put("OrderStatus", 7); // 待服务技师接单
					fuWorkOrderPrincipalTMap.put("IsPrincipal", 0); // 不是主负责人
					fuWorkOrderPrincipalTMap.put("PrincipalId", Long.parseLong(s)); // 人员id
					fuWorkOrderPrincipalTMap.put("Audited", "");
					fuWorkOrderPrincipalTMap.put("Flag", 0);
					fuWorkOrderPrincipalTMap.put("ProcessorId", userid);
					fuWorkOrderPrincipalTMap.put("CreateTime", currentTime);
					workOrderRepairDao.savePrincipal(fuWorkOrderPrincipalTMap); // 插入并保存主工单负责人表数据
				}
			}
			if (CollectionUtils.isNotEmpty(notifyRecordTMapList)) {
				workOrderRepairDao.saveMsgOperation(notifyRecordTMapList); // 插入并保存消息提醒数据
			}
			// 插入并保存工单操作记录表数据
			Map<String, Object> workOrderFlowTMap = new HashMap<String, Object>(); // 新建工单操作记录对象
			workOrderFlowTMap.put("OrderId", workOrderId); // 工单id
			workOrderFlowTMap.put("ProcessorId", userid); // 处理人id
			workOrderFlowTMap.put("OrderStatus", 7); // 待服务技师接单
			workOrderFlowTMap.put("ProcessComment", "");
			workOrderFlowTMap.put("ProLocLon", /*Float.parseFloat((String) map.get("LocLon"))*/MapUtils.getFloatValue(map,"LocLon",  0)); // 经度
			workOrderFlowTMap.put("ProLocLat", /*Float.parseFloat((String) map.get("LocLat"))*/MapUtils.getFloatValue(map,"LocLat",  0)); // 纬度
			workOrderFlowTMap.put("ProLocation",  map.get("Location")); // 操作地点
			workOrderFlowTMap.put("IMEI",  map.get("IMEI")); // 手机串号
			workOrderFlowTMap.put("Flag", 0);
			// workOrderFlowTMap.put("ProcessorId",userid); //创建人
			workOrderFlowTMap.put("CreateTime", currentTime);
			workOrderRepairDao.saveOperation(workOrderFlowTMap); // 插入并保存工单操作记录数据
			String serviceStationId = String.valueOf(map.get("serviceStationID"));
			// 修改工单相关信息
			Map<String, Object> workOrderTMap = new HashMap<String, Object>(); // 新建工单对象

			// 服务渠道是xcec 并且需要外出时，保存出行类型
			if (workOrderT.getIsOutside() == 1) {
				if ((workOrderT.getOrderChannel() == 4 || workOrderT.getOrderChannel() == 109)
						&& StringUtils.isNotEmpty(MapUtils.getString(map, "GoOutType"))) {
					workOrderTMap.put("GoOutType", MapUtils.getIntValue(map, "GoOutType"));
				}
			}
			if (!StringUtils.isBlank((String) map.get("ServiceCarId"))) {
				workOrderTMap.put("ServiceCarId", Long.parseLong((String) map.get("ServiceCarId")));
			}
			if (!StringUtils.isBlank((String) map.get("ServiceCarNo"))) {
				workOrderTMap.put("ServiceCarNo", (String) map.get("ServiceCarNo"));
			}
			workOrderTMap.put("AssignEngineerTime", currentTime); // 指派给服务技师的时间
			workOrderTMap.put("PrincipalId", Long.parseLong(zhuServiceTechnician)); // 当前负责人
			workOrderTMap.put("OrderStatus", 7); // 待服务技师接单
			workOrderTMap.put("Updator", userid);
			workOrderTMap.put("UpdateTime", currentTime);
			workOrderTMap.put("ID", Long.parseLong(workOrderId));
			workOrderTMap.put("OldUpdateTime", (String) map.get("updateTime")); // 前端传来的这条工单的修改时间
			Object emergencyMode = map.get("EmergencyMode");
			if (emergencyMode != null && StringUtils.isNotEmpty((String) emergencyMode)) {
				workOrderTMap.put("EmergencyMode", (String) map.get("EmergencyMode")); // 急救方式：1派人;2派车;3新机检查;4非发动机原因
			}
			if (zjs.getServiceStationID() != workOrderT.getServiceStationId()) {
				//工单的站点id，与指派的技师的所属站点id不同。即创建的是一网，指派给了二网技师，则更新工单的站点id为二网站点id
				workOrderTMap.put("ServiceStationId", zjs.getServiceStationID());
			}
			int updateNum = workOrderTDao.updateZPServiceTechnician(workOrderTMap); // 修改工单信息
			if (updateNum == 0) { // 工单状态没修改成功
				obj.put("status", SMSEnum.type21.getIndex());
				obj.put("msg", SMSEnum.type21.getName());
				obj.put("data", "");
				// 主动回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				// 返回客户
				ParameterTool.writeResponse(response, obj.toString());
				return null;
			}
			// 异步子线程把工单的信息详情同步到CRM
			new Thread(() -> {
				Map<String, Object> parameters = new HashMap<String, Object>();
				parameters.put("orderNo", workOrderT.getOrderNo());
				parameters.put("billStatus", 7);
				parameters.put("actionTime", currentTime);
				parameters.put("directorName", userT.getContact());
				parameters.put("directorPhone", userT.getPhone());
				parameters.put("engineers", engineerMapList); // 技师资质信息同步给CRM
				if (emergencyMode != null && StringUtils.isNotEmpty((String) emergencyMode)) {
					parameters.put("emergencyWay", MapUtils.getIntValue(map, "EmergencyMode")); // 救急方式
				}
				if (workOrderT.getOrderChannel() == 4 || workOrderT.getOrderChannel() == 109) {
					parameters.put("needGoOut", workOrderT.getIsOutside());
					if (workOrderT.getIsOutside() == 1) {
						String vehicleTypeStr = MapUtils.getString(map, "GoOutType");
						if (StringUtils.isEmpty(vehicleTypeStr)) {
							vehicleTypeStr = String.valueOf(workOrderT.getGoOutType());
						}
						parameters.put("vehicleType", Integer.valueOf(vehicleTypeStr));
						parameters.put("goOutType", Integer.valueOf(vehicleTypeStr)); // ccec外出方式是goOutType，发送时再映射crm值
					}
				}
				String serviceCar = MapUtils.getString(map, "ServiceCarNo");
				if (StringUtils.isEmpty(serviceCar)) {
					serviceCar = workOrderT.getServiceCarNo();
				}
				parameters.put("serviceCar", StringUtils.isNotEmpty(serviceCar) ? serviceCar : "");
				parameters.put("secondLevelStationCode", MapUtils.getString(map, "secondLevelStation"));
				parameters.put("phoneIMEI", MapUtils.getString(map, "IMEI", ""));
				parameters.put("positionLat", MapUtils.getFloatValue(map, "LocLat", 0));
				parameters.put("positionLon", MapUtils.getFloatValue(map, "LocLon", 0));
				parameters.put("location", MapUtils.getString(map, "Location", ""));
				if (workOrderT.getOrderChannel() == ccecChannelCompany.getId()) {
					parameters.put("CCSSComplainerOrderNo", workOrderT.getOrderNoCrm());
					parameters.put("CCSSOrderNo", workOrderT.getCCSSOrderNo());
					parameters.put("customerName", workOrderT.getCustomerName());
					parameters.put("customerPhone", workOrderT.getCustomerPhone());
					parameters.put("customerCompany", workOrderT.getCustomerCompanyName());
					parameters.put("faultDesc", workOrderT.getCustomerComplaint());
					Map<String, Object> sSRepair = serviceStationDao.getStationNoAndNameByStationIdAndCompanyId(
							workOrderT.getServiceStationId(), workOrderT.getOrderChannel());
					if (org.apache.commons.collections.MapUtils.isNotEmpty(sSRepair)) {
						parameters.put("stationNo", sSRepair.get("BusinessNo"));
						parameters.put("stationName", sSRepair.get("StationName"));
					} else {
						parameters.put("stationNo", "");
						parameters.put("stationName", "");
					}
				}
				try {
					CRMResponeEntity cRMResponeEntity = CRMApiUtils.getCRMServiceApi().syncOrderStatusToCrm(
							companyTDao.getCompanyInfoByCompanyID(workOrderT.getOrderChannel()).getCompanyNo(),
							platformServiceDao, redisClientUtils, parameters,null);
					if (cRMResponeEntity.getStatus() != 0) {
						log.error("同步工单状态至CRM失败!状态:" + cRMResponeEntity.getStatus() + ",错误信息:"
								+ cRMResponeEntity.getMessage());
					}
				} catch (Exception e) {
					e.printStackTrace();
					log.error("同步工单状态至CRM失败!错误信息:" + e.getMessage(), e);
				}
			}).start();

			obj.put("status", 0);
			obj.put("msg", "指派服务技师成功");
			obj.put("data", "");
			ParameterTool.writeResponse(response, obj.toString());
		} catch (Exception e) {
			ParameterTool.writeErrorResponse(response);
			// 主动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			log.error(e.getMessage(), e);
		}
		return null;
	}

}
